<style type="text/css"> 
td {
	border: 1px solid rgb(170, 170, 170); 
	padding: 5px;
}
</style>

<title>pyftpdlib - FAQs</title>
<a href="http://code.google.com/p/pyftpdlib"><a href="http://code.google.com/p/pyftpdlib"><img id="logo" src="logo.png" /></a></a>

<h1>Frequently asked questions</h1>
<h1><a
 name="Table_of_contents">Table of contents</a></h1>
<ul>
  <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Table_of_contents">Table
of contents</a></li>
  <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Introduction">Introduction</a></li>
  <ul>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#What_is_pyftpdlib?">What
is pyftpdlib?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#What_is_Python?">What
is Python?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#I%27m_not_a_python_programmer._Can_I_use_it_anyway?">I'm
not a python programmer. Can I use it anyway?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Documentation">Documentation</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Mailing_lists">Mailing
lists</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Bug_reporting">Bug
reporting</a></li>
  </ul>
  <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Installing_and_compatibility">Installing
and compatibility</a></li>
  <ul>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#How_do_I_install_pyftpdlib?">How
do I install pyftpdlib?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Which_Python_versions_are_compatible?">Which
Python versions are compatible?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Which_one_is_recommended?">Which
one is recommended?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#What_about_Python_3.x?">What
about Python 3.x?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#On_which_platforms_can_pyftpdlib_be_used?">On
which platforms can pyftpdlib be used?</a></li>
  </ul>
  <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Usage">Usage</a></li>
  <ul>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#How_can_I_run_long-running_tasks_without_blocking_the_server?">How
can I run long-running tasks without blocking the server?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Why_do_I_get_socket.error_%22Permission_denied%22_error_on">Why
do I get socket.error "Permission denied" error on ftpd starting?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#How_can_I_prevent_the_server_version_from_being_displayed?">How
can I prevent the server version from being displayed?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Can_control_upload/download_ratios?">Can
control upload/download ratios?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Are_there_ways_to_limit_connections?">Are
there ways to limit connections?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#I%27m_behind_a_NAT_/_gateway">I'm
behind a NAT / gateway</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#What_is_FXP?">What
is FXP?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Does_pyftpdlib_support_FXP?">Does
pyftpdlib support FXP?</a></li>
  </ul>
  <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Implementation">Implementation</a></li>
  <ul>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Globbing_/_STAT_command_implementation">Globbing
/ STAT command implementation</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#ASCII_transfers_/_SIZE_command_implementation">ASCII
transfers / SIZE command implementation</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#IPv6_support">IPv6
support</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#How_do_I_install_IPv6_support_on_my_system?">How
do I install IPv6 support on my system?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Can_pyftpdlib_be_integrated_with_%22real%22_users_existing">Can
pyftpdlib be integrated with "real" users existing on the system?</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#Does_pyftpdlib_support_FTP_over_TLS/SSL_%28FTPS%29">Does
pyftpdlib support FTP over TLS/SSL (FTPS)</a></li>
    <li><a
 href="http://code.google.com/p/pyftpdlib/wiki/FAQ#What_about_SITE_commands?">What
about SITE commands?</a></li>
  </ul>
</ul>
<h1><a
 name="Introduction">Introduction</a></h1>
<h2><a
 name="What_is_pyftpdlib?">What is pyftpdlib?</a></h2>
<p><a
 name="What_is_pyftpdlib?">pyftpdlib is a high-level
library to easily write asynchronous portable FTP servers with </a><a
 href="http://www.python.org/" rel="nofollow">Python</a>.
</p>
<h2><a
 name="What_is_Python?">What is Python?</a></h2>
<p><a
 name="What_is_Python?">Python is an interpreted,
interactive, object-oriented, easy-to-learn programming language. It is
often compared to <i>Tcl, Perl,
Scheme</i> or <i>Java</i>.
</a></p>
<h2><a
 name="I'm_not_a_python_programmer._Can_I_use_it_anyway?">I'm
not a python programmer. Can I use it anyway?</a></h2>
<p><a
 name="I'm_not_a_python_programmer._Can_I_use_it_anyway?">Yes.
pyftpdlib is a fully working FTP server implementation that can be run
"as is". For example, (after having installed a </a><a
 href="http://www.python.org/download/" rel="nofollow">Python
interpreter</a>) you could run an
anonymous ftp server from cmd-line by running: </p>
<pre ><span
 >python </span><span
 >-</span><span
 >m pyftpdlib</span><span
 >.</span><span
 >ftpserver</span></pre>
<p>Customizing
ftpd for basic tasks like adding users or deciding where log file
should be placed is mostly simply editing variables. This is basically
like learning how to edit a common unix ftpd.conf file and doesn't
really require Python knowledge. Customizing ftpd more deeply requires
a python script which imports pyftpdlib to be written separately. An
example about how this could be done are the scripts contained in the <a
 href="http://code.google.com/p/pyftpdlib/source/browse/trunk/demo"
 rel="nofollow">demo directory</a>.
</p>
<h2><a
 name="Documentation">Documentation</a></h2>
<p><a
 href="http://code.google.com/p/pyftpdlib/" rel="nofollow">http://code.google.com/p/pyftpdlib/</a>
is the primary source for all information about the project including <a
 href="http://code.google.com/p/pyftpdlib/wiki/Install"
 rel="nofollow">Install instructions</a>,
<a
 href="http://code.google.com/p/pyftpdlib/wiki/Tutorial"
 rel="nofollow">Tutorial</a>,
<a
 href="http://code.google.com/p/pyftpdlib/wiki/RFCsCompliance"
 rel="nofollow">RFCs Compliance paper</a>,
<a
 href="http://code.google.com/p/pyftpdlib/w/list" rel="nofollow">Wikis</a>
and the <a
 href="http://code.google.com/p/pyftpdlib/issues/list"
 rel="nofollow">Bug Tracker</a>.
</p>
<h2><a
 name="Mailing_lists">Mailing lists</a></h2>
<p><a
 name="Mailing_lists">There are a number of mailing
lists for pyftpdlib: </a></p>
<p></p>
<table>
  <tbody>
    <tr>
      <td
 >
      <strong>Name</strong>
      </td>
      <td
 >
      <strong>E-mail</strong>
      </td>
      <td
 >
      <strong>Web Interface</strong>
      </td>
      <td
 >
      <strong>Description</strong>
      </td>
    </tr>
    <tr>
      <td
 >
      <a
 href="http://groups.google.com/group/pyftpdlib" rel="nofollow">pyftpdlib</a>
      </td>
      <td
 >

pyftpdlib@googlegroups.com </td>
      <td
 >
      <a
 href="http://groups.google.com/group/pyftpdlib/topics"
 rel="nofollow">topics</a>
      </td>
      <td
 >
This is intended for end user support. </td>
    </tr>
    <tr>
      <td
 >
      <a
 href="http://groups.google.com/group/pyftpdlib-commit"
 rel="nofollow">pyftpdlib-commit</a>
      </td>
      <td
 >
pyftpdlib-commits@googlegroups.com </td>
      <td
 >
      <a
 href="http://groups.google.com/group/pyftpdlib-commit/topics"
 rel="nofollow">topics</a>
      </td>
      <td
 >This
list receives all change notifications for code in the Subversion
repository. Unless you're a pyftpdlib developer you will probably not
be interested in it. </td>
    </tr>
    <tr>
      <td
 >
      <a
 href="http://groups.google.com/group/pyftpdlib-issues"
 rel="nofollow">pyftpdlib-issues</a>
      </td>
      <td
 >
pyftpdlib-issues@googlegroups.com </td>
      <td
 >
      <a
 href="http://groups.google.com/group/pyftpdlib-issues/topics"
 rel="nofollow">topics</a>
      </td>
      <td>
This list receives all change notifications from the <a
 href="http://code.google.com/p/pyftpdlib/issues/list"
 rel="nofollow">Bug Tracker</a>.
Unless you are involved into pyftpdlib development you will probably
not find this useful. </td>
    </tr>
  </tbody>
</table>
<h2><a
 name="Bug_reporting">Bug reporting</a></h2>
<p><a
 name="Bug_reporting">Bug reports should be made via
Google Code </a><a
 href="http://code.google.com/p/pyftpdlib/issues/list"
 rel="nofollow">Issue Tracker</a>.
Patches should be attached to the appropriate bug and not mailed
directly to the mailing lists or any given team member. </p>
<hr>
<h1><a
 name="Installing_and_compatibility">Installing and
compatibility</a></h1>
<h2><a
 name="How_do_I_install_pyftpdlib?">How do I install
pyftpdlib?</a></h2>
<p><a
 name="How_do_I_install_pyftpdlib?">If you are not new
to Python you probably don't need that, otherwise follow the </a><a
 href="http://code.google.com/p/pyftpdlib/wiki/Install"
 rel="nofollow">instructions</a>.
</p>
<h2><a
 name="Which_Python_versions_are_compatible?">Which
Python versions are compatible?</a></h2>
<p><a
 href="http://www.python.org/download/releases/2.3.6/"
 rel="nofollow">Python 2.3</a>
and higher. </p>
<h2><a
 name="Which_one_is_recommended?">Which one is
recommended?</a></h2>
<p><a
 name="Which_one_is_recommended?">Python <strong>2.6</strong>
which provides a faster and cleaner asyncore implementation. </a></p>
<h2><a
 name="What_about_Python_3.x?">What about Python 3.x?</a></h2>
<p><a
 name="What_about_Python_3.x?">Python
3.x is not yet covered because I still have to figure out how to deal
with the str/bytes and encoding differences introduced in the new
Python version =). A porting to Python 3.x is surely in plan, anyway. </a></p>
<h2><a
 name="On_which_platforms_can_pyftpdlib_be_used?">On
which platforms can pyftpdlib be used?</a></h2>
<p><a
 name="On_which_platforms_can_pyftpdlib_be_used?">pyftpdlib
should work on any platform where <strong><i>select()</i></strong>
or <strong><i>poll()</i></strong>
system calls are available and on any Python implementation which
refers to <strong>cPython 2.3</strong>
or superior (e.g cPython 2.6 or PythonCE 2.5). The development team has
mainly tested it under various <strong>Linux</strong>,
<strong>Windows</strong>,
<strong>OS X</strong>
and <strong>FreeBSD</strong>
systems. For FreeBSD is also available a </a><a
 href="http://www.freshports.org/ftp/py-pyftpdlib/"
 rel="nofollow">pre-compiled package</a>
maintained by Li-Wen Hsu &lt;lwhsu@freebsd.org&gt;. Other
Python implementation like <strong><a
 href="http://pythonce.sourceforge.net/" rel="nofollow">PythonCE</a></strong>
are known to work with pyftpdlib and every new version is usually
tested against it. pyftpdlib currently does not work on <strong><a
 href="http://www.jython.org/" rel="nofollow">Jython</a></strong>
since the latest Jython release refers to CPython 2.2.x serie. The best
way to know whether pyftpdlib works on your platform is installing it
and running its test suite. </p>
<hr>
<h1><a
 name="Usage">Usage</a></h1>
<h2><a
 name="How_can_I_run_long-running_tasks_without_blocking_the_server?">How
can I run long-running tasks without blocking the server?</a></h2>
<p><a
 name="How_can_I_run_long-running_tasks_without_blocking_the_server?">pyftpdlib
is an <strong>asynchronous</strong>
FTP server. That means that if you need to run a time consuming task
you have to use a separate Python process or thread for the actual
processing work otherwise the entire asynchronous loop will be blocked.
</a></p>
<p><a
 name="How_can_I_run_long-running_tasks_without_blocking_the_server?">Let's
suppose you want to implement a long-running task every time the server
receives a file. The code snippet below shows the correct way to do it
by using a thread. </a></p>
<p><a
 name="How_can_I_run_long-running_tasks_without_blocking_the_server?">Notice
how we first set <tt>FTPHandler.sleeping</tt>
attribute to <tt>True</tt>,
then we set it back to <tt>False</tt>
when the long-running task has completed.<br>
By setting <tt>sleeping</tt>
attribute to <tt>False</tt>
we temporarily "sleep" the channel which won't be able to send or
receive any more data and won't be closed (disconnected) as long as we
don't set it back to <tt>True</tt>.
This is fundamental when working with threads to avoid race conditions,
dead locks etc. </a></p>
<pre ><a
 name="How_can_I_run_long-running_tasks_without_blocking_the_server?"><span
 >class</span><span
 > </span><span
 >MyHandler</span><span
 >(</span><span
 >ftpserver</span><span
 >.</span><span
 >FTPHandler</span><span
 >):</span><span
 ><br><br>&nbsp; &nbsp; </span><span
 >def</span><span
 > on_file_received</span><span
 >(</span><span
 >self</span><span
 >,</span><span
 > file</span><span
 >):</span><span
 ><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span
 >"""Called every time a file has been received"""</span><span
 ><br><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span
 >def</span><span
 > blocking_task</span><span
 >():</span><span
 ><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time</span><span
 >.</span><span
 >sleep</span><span
 >(</span><span
 >5</span><span
 >)</span><span
 ><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span
 >self</span><span
 >.</span><span
 >sleeping </span><span
 >=</span><span
 > </span><span
 >False</span><span
 ><br><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span
 >self</span><span
 >.</span><span
 >sleeping </span><span
 >=</span><span
 > </span><span
 >True</span><span
 ><br>&nbsp; &nbsp; &nbsp; &nbsp; threading</span><span
 >.</span><span
 >Thread</span><span
 >(</span><span
 >target</span><span
 >=</span><span
 >blocking_task</span><span
 >).</span><span
 >start</span><span
 >()</span></a></pre>
<h2><a
 name="Why_do_I_get_socket.error_&quot;Permission_denied&quot;_error_on">Why
do I get socket.error "Permission denied" error on ftpd starting?</a></h2>
<p><a
 name="Why_do_I_get_socket.error_&quot;Permission_denied&quot;_error_on">Probably
because you're on a Unix system and you're trying to start ftpd as an
unprivileged user. <i>ftpserver.py</i>
binds on port 21 by default and only super-user account (e.g. root) can
bind sockets on such ports. If you want to bind ftpd as non-privileged
user you should set a port higher than 1024. </a></p>
<h2><a
 name="How_can_I_prevent_the_server_version_from_being_displayed?">How
can I prevent the server version from being displayed?</a></h2>
<p><a
 name="How_can_I_prevent_the_server_version_from_being_displayed?">Just
modify <tt>banner</tt>
attribute of <tt>FTPHandler</tt>
class. </a></p>
<h2><a
 name="Can_control_upload/download_ratios?">Can
control upload/download ratios?</a></h2>
<p><a
 name="Can_control_upload/download_ratios?">Yes.
Starting from version 0.5.2 ftpserver.py provides a new class called <tt>ThrottledDTPHandler</tt>.
You can set speed limits by modifying <tt>read_limit</tt>
and <tt>write_limit</tt>
class attributes as it is shown in </a><a
 href="http://pyftpdlib.googlecode.com/svn/trunk/demo/throttled_ftpd.py"
 rel="nofollow">throttled_ftpd.py</a>
demo script. </p>
<h2><a
 name="Are_there_ways_to_limit_connections?">Are there
ways to limit connections?</a></h2>
<p><a
 name="Are_there_ways_to_limit_connections?"><tt>FTPServer</tt>
class comes with two overridable attributes defaulting to zero (no
limit): <tt>max_cons</tt>,
which sets a limit for maximum simultaneous connection to handle by
ftpd and <tt>max_cons_per_ip</tt>
which set a limit for connections from the same IP address. Overriding
these variables is always recommended to avoid DoS attacks. </a></p>
<h2><a
 name="I'm_behind_a_NAT_/_gateway">I'm behind a NAT /
gateway</a></h2>
<p><a
 name="I'm_behind_a_NAT_/_gateway">When
behind a NAT a ftp server needs to replace the IP local address
displayed in PASV replies and instead use the public address of the NAT
to allow client to connect. By overriding <tt>masquerade_address</tt>
attribute of <tt>FTPHandler</tt>
class you will force pyftpdlib to do such replacement. However, one
problem still exists. The passive FTP connections will use ports from
1024 and up, which means that you must forward all ports 1024-65535
from the NAT to the FTP server! And you have to allow many (possibly)
dangerous ports in your firewalling rules! To resolve this, simply
override <tt>passive_ports</tt>
attribute of <tt>FTPHandler</tt>
class to control what ports pyftpdlib will use for its passive data
transfers. Value expected by <tt>passive_ports</tt>
attribute is a list of integers (e.g. range(60000, 65535)) indicating
which ports will be used for initializing the passive data channel. </a></p>
<h2><a
 name="What_is_FXP?">What is FXP?</a></h2>
<p><a
 name="What_is_FXP?">FXP is part of the name of a
popular Windows FTP client: </a><a
 href="http://www.flashfxp.com" rel="nofollow">http://www.flashfxp.com</a>.
This client has made the name "FXP" commonly used as a synonym for
site-to-site FTP transfers, for transferring a file between two remote
FTP servers without the transfer going through the client's host.
Sometimes "FXP" is referred to as a protocol; in fact, it is not. The
site-to-site transfer capability was deliberately designed into <a
 href="http://www.faqs.org/rfcs/rfc959.html" rel="nofollow">RFC-959</a>.
More info can be found here: <a
 href="http://www.proftpd.org/docs/howto/FXP.html" rel="nofollow">http://www.proftpd.org/docs/howto/FXP.html</a>.
</p>
<h2><a
 name="Does_pyftpdlib_support_FXP?">Does pyftpdlib
support FXP?</a></h2>
<p><a
 name="Does_pyftpdlib_support_FXP?">Yes. It is
disabled by default for security reasons (see </a><a
 href="http://gim.org.pl/rfcs/rfc2577.html" rel="nofollow">RFC-2257</a>
and <a
 href="http://www.cert.org/advisories/CA-1997-27.html"
 rel="nofollow">FTP bounce attack description</a>)
but in case you want to enable it just set to True the <tt>permit_foreign_addresses</tt>
attribute of <tt>FTPHandler</tt>
class. </p>
<hr>
<h1><a
 name="Implementation">Implementation</a></h1>
<h2><a
 name="Globbing_/_STAT_command_implementation">Globbing
/ STAT command implementation</a></h2>
<p><a
 name="Globbing_/_STAT_command_implementation">Globbing
is a common Unix shell mechanism for expanding wildcard patterns to
match multiple filenames. When an argument is provided to the <strong>STAT</strong>
command, ftpd should return directory listing over the command channel.
</a><a
 href="http://www.faqs.org/rfcs/rfc959.html" rel="nofollow">RFC-959</a>
does not explicitly mention globbing; this means that FTP servers are
not required to support globbing in order to be compliant. However,
many FTP servers do support globbing as a measure of convenience for
FTP clients and users. In order to search for and match the given
globbing expression, the code has to search (possibly) many
directories, examine each contained filename, and build a list of
matching files in memory. Since this operation can be quite intensive,
both CPU- and memory-wise, pyftpdlib <i>does
not</i> support globbing. </p>
<h2><a
 name="ASCII_transfers_/_SIZE_command_implementation">ASCII
transfers / SIZE command implementation</a></h2>
<p><a
 name="ASCII_transfers_/_SIZE_command_implementation">Properly
handling the SIZE command when TYPE ASCII is used would require to scan
the entire file to perform the ASCII translation logic
(file.read().replace(os.linesep, '\r\n')) and then calculating the len
of such data which may be different than the actual size of the file on
the server. Considering that calculating such result could be very
resource-intensive it could be easy for a malicious client to try a DoS
attack, thus pyftpdlib rejects SIZE when the current TYPE is ASCII.
However, clients in general should not be resuming downloads in ASCII
mode. Resuming downloads in binary mode is the recommended way as
specified in </a><a
 href="http://www.faqs.org/rfcs/rfc3659.html" rel="nofollow">RFC-3659</a>.
</p>
<h2><a
 name="IPv6_support">IPv6 support</a></h2>
<p><a
 name="IPv6_support">Starting from version 0.4.0
pyftpdlib <i>supports</i>
IPv6 (</a><a
 href="http://www.faqs.org/rfcs/rfc2428.html" rel="nofollow">RFC-2428</a>).
If you use IPv6 and want your FTP daemon to do so just pass a valid
IPv6 address to the FTPServer class constructor. Example: </p>
<pre ><span
 >&gt;&gt;&gt;</span><span
 > </span><span
 >from</span><span
 > pyftpdlib </span><span
 >import</span><span
 > ftpserver<br></span><span
 >&gt;&gt;&gt;</span><span
 > address </span><span
 >=</span><span
 > </span><span
 >(</span><span
 >"::1"</span><span
 >,</span><span
 > </span><span
 >21</span><span
 >)</span><span
 > &nbsp;</span><span
 ># listen on localhost, port 21</span><span
 ><br></span><span
 >&gt;&gt;&gt;</span><span
 > ftpd </span><span
 >=</span><span
 > ftpserver</span><span
 >.</span><span
 >FTPServer</span><span
 >(</span><span
 >address</span><span
 >,</span><span
 > ftpserver</span><span
 >.</span><span
 >FTPHandler</span><span
 >)</span><span
 ><br></span><span
 >&gt;&gt;&gt;</span><span
 > ftpd</span><span
 >.</span><span
 >serve_forever</span><span
 >()</span><span
 ><br></span><span
 >Serving</span><span
 > FTP on </span><span
 >::</span><span
 >1</span><span
 >:</span><span
 >21</span></pre>
<h2><a
 name="How_do_I_install_IPv6_support_on_my_system?">How
do I install IPv6 support on my system?</a></h2>
<p><a
 name="How_do_I_install_IPv6_support_on_my_system?">If
you want to install IPv6 support on Linux run "modprobe ipv6", then
"ifconfig". This should display the loopback adapter, with the address
"::1". You should then be able to listen the server on that address,
and connect to it. </a></p>
<p><a
 name="How_do_I_install_IPv6_support_on_my_system?">On
Windows (XP SP2 and higher) run "netsh int ipv6 install". Again, you
should be able to use IPv6 loopback afterwards. </a></p>
<h2><a
 name="Can_pyftpdlib_be_integrated_with_&quot;real&quot;_users_existing">Can
pyftpdlib be integrated with "real" users existing on the system?</a></h2>
<p><a
 name="Can_pyftpdlib_be_integrated_with_&quot;real&quot;_users_existing">Yes.
By using the proper system dependent authorizer pyftpdlib can look into
the system account database to authenticate users. Starting from
version 0.4.0 the <tt>DummyAuthorizer</tt>
class provides two new methods: <tt>impersonate_user()</tt>
and <tt>terminate_impersonation()</tt>.
System dependent authorizers subclassing the dummy authorizer can
assume the id of real users by overriding them as necessary. Every time
the FTP server is going to access the filesystem (e.g. for creating or
renaming a file) it will temporarily impersonate the currently logged
on user, execute the filesystem call and then switch back to the user
who originally started the server. Example UNIX and Windows FTP servers
contained in the </a><a
 href="http://code.google.com/p/pyftpdlib/source/browse/#svn/trunk/demo"
 rel="nofollow">demo directory</a>
implement both real user impersonation and authentication against the
system users database. </p>
<h2><a
 name="Does_pyftpdlib_support_FTP_over_TLS/SSL_(FTPS)">Does
pyftpdlib support FTP over TLS/SSL (FTPS)</a></h2>
<p><a
 name="Does_pyftpdlib_support_FTP_over_TLS/SSL_(FTPS)">The
standard code base does not offer any "official" FTPS support yet but
starting from version </a><a
 href="http://pyftpdlib.googlecode.com/files/pyftpdlib-0.5.1.tar.gz"
 rel="nofollow">0.5.1</a>
the <a
 href="http://code.google.com/p/pyftpdlib/source/browse/trunk/demo"
 rel="nofollow">demo</a>
directory contains a <a
 href="http://code.google.com/p/pyftpdlib/source/browse/trunk/demo/tls_ftpd.py"
 rel="nofollow">script</a>
which implements a simple FTPS daemon supporting both TLS and SSL
protocols and <strong>AUTH</strong>,
<strong>PBSZ</strong>
and <strong>PROT</strong>
commands as defined in <a
 href="http://www.ietf.org/rfc/rfc4217.txt" rel="nofollow">RFC-4217</a>.
</p>
<h2><a
 name="What_about_SITE_commands?">What about SITE
commands?</a></h2>
<p><a
 name="What_about_SITE_commands?">No SITE commands aside from <strong>SITE HELP</strong> 
  are implemented by default. The user willing to add support for a specific SITE 
  command (e.g. <strong>SITE CHMOD</strong>) has to define a new <tt>ftp_SITE_%CMD%</tt> 
  method in the <tt>FTPHandler</tt> subclass. </a></p>
<p>&nbsp;</p>
